<?php

/**
 * Louder Cache
 *
 * LICENSE
 *
 * This source file is subject to the New BSD License that is bundled
 * with this package in the file docs/LICENSE.txt.
 *
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to info@loudertechnology.com so we can send you a copy immediately.
 *
 * @category Louder
 * @package ClusterNodeManager
 * @copyright Copyright (c) 2005-2009 Andres Felipe Gutierrez (gutierrezandresfelipe at gmail.com)
 * @license New BSD License
 */

/**
 * Servidor que administrar las peticiones al cluster
 *
 * @category Louder
 * @package ClusterNodeManager
 * @copyright Copyright (c) 2005-2009 Andres Felipe Gutierrez (gutierrezandresfelipe at gmail.com)
 * @license New BSD License
 */
class ClusterNodeManager {

	/**
	 * Nodos administrados
	 *
	 * @var array
	 */
	private static $_nodes = array();

	/**
	 * Nodos caidos
	 *
	 * @var array
	 */
	private static $_failedNodes = array();

	/**
	 * Agrega un nodo al administrador
	 *
	 * @param ClusterNode $node
	 */
	public static function addNode(ClusterNode $node){
		self::$_nodes[] = $node;
	}

	/**
	 * Devuelve los nodos administrados
	 *
	 * @return array
	 */
	public static function getManagedNodes(){
		self::$_failedNodes = self::_getFailedNodes();
		$availableNodes = array();
		$failedNodesNumber = count(self::$_failedNodes);
		foreach(self::$_nodes as $node){
			if($failedNodesNumber>0){
				if(!in_array($node->getName(), array_keys(self::$_failedNodes))){
					$availableNodes[] = $node;
				}
			} else {
				$availableNodes[] = $node;
			}
		}
		return $availableNodes;
	}

	/**
	 * Devuelve los nombres de los nodos que estan caidos
	 *
	 * @access private
	 * @return string
	 * @static
	 */
	private static function _getFailedNodes(){
		$failedNodes = MemoryRegistry::get('failedNodes');
		if(is_bool($failedNodes)){
			$failedNodes = array();
		}
		return $failedNodes;
	}

	/**
	 * Almacena en memoria los nodos caidos
	 *
	 * @access private
	 * @static
	 */
	private static function _storeFailedNodes($failedNodes){
		MemoryRegistry::set('failedNodes', $failedNodes);
	}

	/**
	 * Agrega un nodo que esta caido a la lista de caidos
	 *
	 * @param ClusterNode $node
	 */
	public static function addFailuredNode(ClusterNode $node){
		$nodeExists = true;
		self::$_failedNodes = self::_getFailedNodes();
		if(in_array($node->getName(), array_keys(self::$_failedNodes))){
			return;
		}
		self::$_failedNodes[$node->getName()] = time();
		self::_storeFailedNodes(self::$_failedNodes);
	}

	/**
	 * Devuelve los nombres de los nodos caidos
	 *
	 * @return string
	 */
	public static function getFailuredNodes(){
		return self::_getFailedNodes();
	}

}
